package com.walle.ak47.commons.jaxrs.cxf.interceptor;

import java.util.Date;
import java.util.List;
import java.util.TreeMap;

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.XMLMessage;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.walle.ak47.commons.jaxrs.cxf.header.HeaderHolder;
import com.walle.ak47.commons.jaxrs.cxf.header.HeaderInfo;
import com.walle.ak47.commons.utils.AESCodec;
import com.walle.ak47.commons.utils.ConvertUtils;
import com.walle.ak47.commons.utils.DateUtils;
import com.walle.ak47.commons.utils.PropertiesReader;
import com.walle.ak47.commons.utils.RSASecurityUtil;
import com.walle.ak47.commons.utils.StringUtils;

public class SecureCheckHander extends AbstractPhaseInterceptor<XMLMessage> {
	
	private static final Logger LOG = LoggerFactory.getLogger(SecureCheckHander.class);

	private String privateKey = null ;
	
	public SecureCheckHander() {
		super(Phase.PRE_INVOKE);// 该拦截器在调用前拦截HttpHeader信息
	}
	
	public SecureCheckHander( String privteKey) {
		super(Phase.PRE_INVOKE);// 该拦截器在调用前拦截HttpHeader信息
		this.privateKey = privteKey ;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public void handleMessage(XMLMessage msg) throws Fault {
		try {
			TreeMap<String, List> map = (TreeMap<String, List>) msg.get(Message.PROTOCOL_HEADERS);
			List list = (List) map.get("x-auth-header");
			if (list == null || list.size() == 0) {
				throw new Exception("X-AUTH-HEADER不存在，验证失败!");
			}
			String encode = list.get(0).toString();
			if (StringUtils.isBlank(encode)) {
				throw new Exception("X-AUTH-HEADER不存在，验证失败!");
			}
			//rsa解密
			String sAuthenticate = RSASecurityUtil.decrypt(encode, this.privateKey ) ;
			//校验header合法性
			String[] param = StringUtils.split(sAuthenticate, ",");
			if (param == null || param.length != 3
					|| StringUtils.isBlank(param[0])
					|| StringUtils.isBlank(param[1])
					|| StringUtils.isBlank(param[2])) {
				throw new Exception("无效的X-AUTH-HEADER");
			}
			String authenToken = AESCodec.decode(param[0]);
			if(!authenToken.equals(param[1])){
				throw new Exception("无效的systemId");
			}
			//检验时效性，默认不能超过5分钟
			long begin = Long.parseLong(param[2]);
			long now = System.currentTimeMillis();
			int effectiveMinutes = 5;
			int second = 10 ;
			if(StringUtils.isNotBlank(PropertiesReader.getWebConfig("minutes"))){
				effectiveMinutes = Integer.parseInt(PropertiesReader.getWebConfig("minutes"));
			}
			if(StringUtils.isNotBlank(PropertiesReader.getWebConfig("second"))){
				second = Integer.parseInt(PropertiesReader.getWebConfig("second"));
			}
			
			long timeGap =  (now-begin)/1000 ;
			long effectiveTime = timeGap/60 ;
			
			if ( timeGap < 0 && Math.abs(timeGap) > second )
			{
				LOG.error( "Server date is {},client date is {}", DateUtils.dateToStr( new Date(now)) , DateUtils.dateToStr( new Date(begin)) );
				throw new Exception("客户端系统时间不正确");
			}
				
			if( effectiveTime > effectiveMinutes ){
				LOG.error( "Server date is {},client date is {}", DateUtils.dateToStr( new Date(now)) , DateUtils.dateToStr( new Date(begin)) );
				throw new Exception("请求超时");
			}
			
			HeaderHolder.setHeader( new HeaderInfo( param[0], ConvertUtils.toInt(param[1]), new Date().getTime() ));
		} catch (Exception e) {
			throw new Fault(new IllegalAccessException(e.getMessage()));
		}
	}

	public String getPrivateKey() {
		return privateKey;
	}

	public void setPrivateKey(String privateKey) {
		this.privateKey = privateKey;
	}
	
}
